以下筆記摘錄自『 The Go Workshop 』。
列舉是一種定義一系列常數的方式,常數是整數且彼此相關。Go雖然沒有內建列舉專用的型別,但提供了一種稱為iota的工具供使用。
For example,
const (
Sunday = 0
Monday = 1
Tuseday = 2
...
Saturday = 6
)
使用iota可以協助管理以上的常數清單,使列舉清單更容易建立、修改。
const (
Sunday = iota
Monday
Tuseday
...
Saturday
)
所有變數都有其運作範圍(或稱層級、作用域)。最上層的範圍是套件(package)範圍。
變數範圍的上下層關係在編譯程式時就決定好,不是等到執行階段才決定。當某段程式碼存取某個變數時,Go語言會檢查該程式碼的作用範圍。範圍內找不到該名稱,就會往上一層範圍找,一直找到最頂層的套件範圍為止。途中找到同名變數,Go就會停止搜尋,並使用那個變數,但若到頂端還是找不到,就會拋出錯誤。
package main
import "fmt"
var level = "pkg"
func main() {
fmt.Println("Main start :", level) //main()層級
if true {
fmt.Println("Block start :", level) //底下if層級
funcA()
}
}
func funcA() {
fmt.Println("funcA start :", level) //funcA()層級
}
因為Go語言一找到變數,Go就會停止搜尋,並使用那個變數,所以導致遮蔽現象
package main
import "fmt"
var level = "pkg"
func main() {
fmt.Println("Main start :", level)
level := 42
if true {
fmt.Println("Block start :", level)
funcA()
}
fmt.Println("Main end :", level)
}
func funcA() {
fmt.Println("funcA start :", level)
}
輸出:
Main start : pkg
Block start : 42
funcA start : pkg
Main end : 42
由以上可得出,子範圍的level變數『遮蔽』了套件範圍的level變數。
其中特別注意的是,當我們呼叫funcA()時,Go語言動用了靜態範圍解析,他不會管funcA()在哪裏被呼叫,因此funcA()仍是套件層級的level變數!